//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
#include "globals.h"

static s8 create_pool(struct client *c,struct msg *m)
{
  s8 r;
  if(m->req_dws<4){
    PERR("client(%d):fatal:shm::create_pool missing data\n",c->so);
    r=LWL_ERR;goto exit;
  }

  if(m->fd==MSG_FDS_MAX||(m->fds[m->fd]==-1)){
    PERR("client(%d):fatal:shm::create_pool missing the pool file descriptor\n",
                                                                         c->so);
    r=LWL_ERR;goto exit;
  }

  LOG_WIRE("client(%d):shm::create_pool shm_id=%u fd=%d sz=%d\n",c->so,
                                        m->req[2],m->fds[m->fd],(s32)m->req[3]);

  r=shm_create_pool(c,m->req[2],m->fds[m->fd++],(s32)m->req[3]);
exit:
  return r;
}

s8 wl_shm_req(struct client *c,struct msg *m)
{
  s8 r;
  switch(m->req_op){
  case WL_SHM_CREATE_POOL:
    r=create_pool(c,m);
    break;
  default:
    PERR("client(%d):fatal:shm unknown opcode %u\n",c->so,m->req_op);
    r=LWL_ERR;
  };
  return r;
}

#define EV_FORMAT_DWS 3
s8 wl_shm_ev_format(struct client *c,u32 shm_id,u32 fmt)
{
  u32 ev[EV_FORMAT_DWS];

  ev[0]=shm_id;
  u16 ev_sz=EV_FORMAT_DWS*sizeof(u32);
  ev[1]=ev_sz<<16|WL_SHM_FORMAT;
  ev[2]=fmt;

  struct io_vec iov;
  iov.base=&ev;
  iov.len=ev_sz;

  struct msg_hdr msg;
  memset(&msg,0,sizeof(msg));
  msg.iov=&iov;
  msg.iov_len=1;

  LOG_WIRE("client(%d):shm::format fmt=%u shm_id=%u\n",c->so,fmt,shm_id);

  l r;
  while(1){r=sendmsg(c->so,&msg,0); if(r!=-EINTR) break;}

  if(ISERR(r)){
    PERR("client(%d):fatal(%ld):shm::format unable to send event\n",r,c->so);
    r=LWL_ERR;goto exit;
  }

  if(r!=ev_sz){
    PERR("client(%d):fatal:shm::format only %ld/%ld were sent\n",c->so,r,ev_sz);
    r=LWL_ERR;goto exit;
  }

  r=LWL_OK;

exit:
  return (s8)r;
}
